using System;

namespace SharpDX.Toolkit.Graphics
{
	/// <summary>
	/// Describes a mipmap.
	/// </summary>
	public class MipMapDescription : IEquatable<MipMapDescription>
	{
		/// <summary>
		/// Width of this mipmap.
		/// </summary>
		public readonly int Width;

		/// <summary>
		/// Height of this mipmap.
		/// </summary>
		public readonly int Height;

		/// <summary>
		/// Width of this mipmap.
		/// </summary>
		public readonly int WidthPacked;

		/// <summary>
		/// Height of this mipmap.
		/// </summary>
		public readonly int HeightPacked;

		/// <summary>
		/// Depth of this mipmap.
		/// </summary>
		public readonly int Depth;

		/// <summary>
		/// RowStride of this mipmap (number of bytes per row).
		/// </summary>
		public readonly int RowStride;

		/// <summary>
		/// DepthStride of this mipmap (number of bytes per depth slice).
		/// </summary>
		public readonly int DepthStride;

		/// <summary>
		/// Size in bytes of this whole mipmap.
		/// </summary>
		public readonly int MipmapSize;

		/// <summary>
		/// Initializes a new instance of the <see cref="T:SharpDX.Toolkit.Graphics.MipMapDescription" /> class.
		/// </summary>
		/// <param name="width">The width.</param>
		/// <param name="height">The height.</param>
		/// <param name="depth">The depth.</param>
		/// <param name="rowStride">The row stride.</param>
		/// <param name="depthStride">The depth stride.</param>
		/// <param name="widthPacked">The packed width.</param>
		/// <param name="heightPacked">The packed height.</param>
		public MipMapDescription(int width, int height, int depth, int rowStride, int depthStride, int widthPacked, int heightPacked)
		{
			Width = width;
			Height = height;
			Depth = depth;
			RowStride = rowStride;
			DepthStride = depthStride;
			MipmapSize = depthStride * depth;
			WidthPacked = widthPacked;
			HeightPacked = heightPacked;
		}

		public bool Equals(MipMapDescription other)
		{
			if ((object)other == null)
			{
				return false;
			}
			if ((object)this == other)
			{
				return true;
			}
			if (Width == other.Width && Height == other.Height && WidthPacked == other.WidthPacked && HeightPacked == other.HeightPacked && Depth == other.Depth && RowStride == other.RowStride && MipmapSize == other.MipmapSize)
			{
				return DepthStride == other.DepthStride;
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj == null)
			{
				return false;
			}
			if (this == obj)
			{
				return true;
			}
			if (obj.GetType() != GetType())
			{
				return false;
			}
			return Equals((MipMapDescription)obj);
		}

		public override int GetHashCode()
		{
			return (((((((((((((Width * 397) ^ Height) * 397) ^ WidthPacked) * 397) ^ HeightPacked) * 397) ^ Depth) * 397) ^ RowStride) * 397) ^ MipmapSize) * 397) ^ DepthStride;
		}

		/// <summary>
		/// Implements the ==.
		/// </summary>
		/// <param name="left">The left.</param>
		/// <param name="right">The right.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator ==(MipMapDescription left, MipMapDescription right)
		{
			return object.Equals(left, right);
		}

		/// <summary>
		/// Implements the !=.
		/// </summary>
		/// <param name="left">The left.</param>
		/// <param name="right">The right.</param>
		/// <returns>The result of the operator.</returns>
		public static bool operator !=(MipMapDescription left, MipMapDescription right)
		{
			return !object.Equals(left, right);
		}
	}
}
